package com.yc.damai.damaiindex.web;

import com.yc.damai.bean.Result;
import com.yc.damai.bean.SecKillOrder;
import com.yc.damai.damaiindex.web.fegin.OtherAction;
import com.yc.damai.entity.DmProduct;
import lombok.Data;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * Company 源辰信息
 *
 * @author navy
 * @date 2024/9/13
 * Email haijunzhou@hnit.edu.cn
 */

@RestController
@RequestMapping("secKill")
public class SecKillDo {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    OtherAction otherAction;

    // 手动开启秒杀
    @RequestMapping("start")
    public Result start(){
        // 判断
        if (redisTemplate.hasKey("SecKillInfo")) {
            return new Result(-1,"秒杀活动已经开始!",null);
        }
        // 查询 10 库存最多的商品,
        List<DmProduct> products = otherAction.querySecKillProduct();
        SecKillInfo secKillInfo = new SecKillInfo();
        secKillInfo.setProducts(products);
        secKillInfo.setBegin(new Date());
        secKillInfo.setEnd(new Date(   secKillInfo.getBegin().getTime() + 1000*60*10  ));
        // 保存数据到Redis中
        ValueOperations opsForValue = redisTemplate.opsForValue();
        opsForValue.set("SecKillInfo",secKillInfo);

        // 将商品库存单独保存
        for (DmProduct product : secKillInfo.getProducts()) {
            opsForValue.set("secKill:" + product.getId(), product.getStore());
        }

        // 加入延时任务
        taskScheduler.schedule(()->{
            finish();
        }, secKillInfo.getEnd());

        return new Result(1,"秒杀活动开始!",null);
    }

    @Autowired
    TaskScheduler taskScheduler;

    public void finish(){
        System.out.println("===========秒杀活动结束============");
        SecKillInfo secKillInfo = (SecKillInfo) redisTemplate.opsForValue().get("SecKillInfo");
        // TODO 此处代码待优化
        Result result = otherAction.updateSecKillProduct(secKillInfo.getProducts());
        System.out.println("result = " + result);
        redisTemplate.delete("SecKillInfo");
    }

    @Autowired
    RabbitTemplate rabbitTemplate;

    @RequestMapping("commit")
    public Result commit(int pid, int uid,
                         @RequestParam(defaultValue = "1") int cnt){
        // 验证
        if (redisTemplate.hasKey("secKill:" + pid) == false) {
            return new Result(-1, "该商品不是秒杀商品", null);
        }
        // TODO 判断用户是否秒杀过该商品
        // 减库存
        ValueOperations opsForValue = redisTemplate.opsForValue();
        Integer store = (Integer) opsForValue.get("secKill:" + pid);
        opsForValue.set("secKill:" + pid, ++store);
        // 生成订单消息 => 消息队列
        SecKillOrder order = new SecKillOrder(uid,pid,cnt);
        rabbitTemplate.convertAndSend("secKillQueue", order);
        return new Result(1,"秒杀成功!",null);
    }

    @RequestMapping("query")
    public Result query(){
        if (redisTemplate.hasKey("SecKillInfo") == false) {
            return new Result(-1,"秒杀活动未开始!",null);
        }
        SecKillInfo secKillInfo = (SecKillInfo) redisTemplate.opsForValue().get("SecKillInfo");
        return new Result(1,"秒杀商品", secKillInfo);
    }

    @PostConstruct
    void init(){
        // 清除redis中的秒杀数据
        redisTemplate.delete("SecKillInfo");
        Set keys = redisTemplate.keys("secKill:*");
        for (Object key : keys) {
            redisTemplate.delete(key);
        }
    }

}


@Data
class SecKillInfo implements java.io.Serializable{
    List<DmProduct> products;
    Date begin;
    Date end;
}
